package com.inspinia.upms.common.filter;

import com.baomidou.kisso.SSOHelper;
import com.inspinia.base.cache.RedisUtil;
import com.inspinia.base.common.model.UserCacheKeys;
import com.inspinia.config.common.config.RedisConfig;
import com.inspinia.upms.common.model.user.UpmsUser;
import org.apache.commons.lang3.SerializationUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.LogoutFilter;
import org.crazycake.shiro.RedisManager;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;
import java.util.ArrayList;

public class MyLogoutFilter extends LogoutFilter {

    private static final String PARAMETER_NAME_KICKOUT = "kickout";
    private static final String PARAMETER = "?kickout=1";

    private RedisManager redisManager;

    @Override
    protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
        beforeLogout();
        SSOHelper.clearLogin((HttpServletRequest) request, (HttpServletResponse) response);
        return super.preHandle(request, response);
    }

    @Override
    protected String getRedirectUrl(ServletRequest request, ServletResponse response, Subject subject) {
        //拼接返回路径
        String kickOut = request.getParameter(PARAMETER_NAME_KICKOUT);
        if (StringUtils.isNotEmpty(kickOut)) {
            return super.getRedirectUrl() + PARAMETER;
        }
        return super.getRedirectUrl(request, response, subject);
    }
    /**
     * 退出前的操作
     */
    public void beforeLogout() {
        Subject subject = SecurityUtils.getSubject();
        if (subject.getPrincipal() instanceof UpmsUser){
            if (subject.getPrincipal() != null) {
                removeUserLinetCache();
                removeUsernameSessionCache();
            }
        }
    }


    /**
     * 删除用户在线缓存
     */
    private void removeUserLinetCache() {
        Subject subject = SecurityUtils.getSubject();
        UpmsUser shiroUser = (UpmsUser) subject.getPrincipal();
//        String userLineStatusKey = UserCacheKeys.genUserLineStatusKey(shiroUser.getUserId());
//        RedisUtil.delete(userLineStatusKey.getBytes());
    }

    /**
     * 删除用户的sessionId
     * @param req
     */
    private void removeUserSessionId(HttpServletRequest req){
        String sessionKey = UserCacheKeys.getSessionKey(req.getSession().getId());
        RedisUtil.delete(sessionKey.getBytes());
    }

    /**
     * 删除用户名和sessionId关系的缓存数据
     */
    public void removeUsernameSessionCache() {

        //获取用户session和用户名
        Subject subject = SecurityUtils.getSubject();
        Serializable sessionId = subject.getSession().getId();
        UpmsUser user = (UpmsUser) subject.getPrincipal();

        //从用户名和sessionId缓存中找到，然后清除该sessionId
        String usernameSessionKey = UserCacheKeys.getUsernameSessionKey(user.getUserName());
        byte[] bytes = getRedisManager().get(usernameSessionKey.getBytes());
        if (bytes != null) {
            ArrayList<Serializable> sessionIds = SerializationUtils.deserialize(bytes);
            sessionIds.remove(sessionId);
            //当usernmae对应的session集合没有元素时，就将该key删除。
            if (sessionIds.size() == 0) {
                getRedisManager().del(usernameSessionKey.getBytes());
            } else {
                getRedisManager().set(usernameSessionKey.getBytes(), SerializationUtils.serialize(sessionIds), RedisConfig.timeout);
            }
        }
    }

    public RedisManager getRedisManager() {
        return redisManager;
    }

    public void setRedisManager(RedisManager redisManager) {
        this.redisManager = redisManager;
    }
}
